#pragma once
#include "cgzITask.h"
class redisContext;
class redisReply;

enum class cgzRedisCmdType
{
    SELECT,
    GET,
    SET,
    DEL,
    HGET,
    HMGET,
    HSET,
    HSETNX,
    HMSET,
    HGETALL,
    HDEL,
    HEXISTS,
    HLEN,
    HKEYS,
    HVALS,
    HSCAN,
    HINCRBY,
    HINCRBYFLOAT,
    HRANDFIELD,
    HSTRLEN,
    LPUSH,
    RPUSH,
    LPOP,
    RPOP,
    LRANGE,
    LTRIM,
    SADD,
    SREM,
    SPOP,
    SMOVE,
    SCARD,
    SISMEMBER,
    SMEMBERS,
    SRANDMEMBER,
    SDIFF,
    SINTER,
    SUNION,
    SUNIONSTORE,
    SINTERSTORE,
    SDIFFSTORE,
    ZADD,
    ZREM,
    ZINCRBY,
    ZCARD,
    ZRANGE,
    ZRANGEBYSCORE,
    ZRANK,
    ZCOUNT,
    ZSCORE,
    ZREMRANGEBYRANK,
    ZREMRANGEBYSCORE,
    ZDIFF,
    ZINTER,
    ZUNION,
    ZDIFFSTORE,
    ZINTERSTORE,
    ZUNIONSTORE,
    XADD,
    XREAD,
    XGROUP,
    XREADGROUP,
    XACK,
    XINFO,
    XDEL,
    XRANGE,
    XREVRANGE,
    XTRIM,
    XCLAIM,
    XPENDING,
    XLEN,
    TTL,
    PTTL,
    PERSIST,
    EXPIRE,
    PEXPIRE,
    EXPIREAT,
    PEXPIREAT,
    TYPE,
    KEYS,
    RANDOMKEY,
    MOVE,
    RENAME,
    SORT,
    SCAN,
    SCRIPT,
    EVALSHA,
    EVAL,
};

enum class cgzRedisCode
{
    NONE,         // 无响应
    AUTH_SUCCESS, // 认证成功
    EXEC_REQUEST, // 执行请求
    EXEC_REPLY,   // 执行回复
};

class cgzCRedisReply : public cgzIData
{
public:
    friend class cgzCHRedis;
    cgzCRedisReply(cgzRedisCode code);
    virtual ~cgzCRedisReply();

public:
    cgzRedisCode m_code;
};

class cgzCRedisCmd : public cgzCRedisReply
{
public:
    friend class cgzCHRedis;
    cgzCRedisCmd(const cgzRedisCmdType cmd, const int cookid = -1);
    virtual ~cgzCRedisCmd();

public:
    // 请求参数
    cgzRedisCmdType m_cmd;
    std::vector<std::string> m_args;
    // 回调凭证
    long m_cookid;
    // 是否回调
    bool m_ret;
    // 释放错误
    bool m_err;
    // 响应参数
    redisReply *m_reply;
};

class cgzCHRedis : public cgzITask
{
public:
    cgzCHRedis(cgzCThreadPool *pool, const char *name, const char *ip, const char *auth, const int port, const int idb, const int cid);
    virtual ~cgzCHRedis();

public:
    bool run(int64_t nms) override;

public:
    bool connect();
    void authret();

protected:
    std::string m_ip;
    std::string m_auth;
    int m_port;
    int m_idb;
    int m_cid;
    int m_fd;
    bool m_firstAuth;

private:
    redisContext *m_redis;
    const char *m_argv[4096];
    size_t m_argvlen[4096];
};
